package com.elite.groovy.callback
import com.elite.groovy.util.EliteBean
import cn.com.elite.PropertiesUtil
import com.elite.groovy.util.Util
import cn.com.kh.HttpClientProxy
import com.elite.groovy.kh.KHDBConfig
import com.elite.groovy.kh.KHUtil
import com.alibaba.fastjson.JSON
import com.wisdge.utils.StringUtils
import net.sf.json.JSONObject

import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.apache.http.Header
import org.apache.http.HttpEntity
import org.apache.http.HttpHost
import org.apache.http.HttpResponse
import org.apache.http.client.methods.HttpGet
import org.apache.http.impl.client.DefaultHttpClient
import org.apache.http.util.EntityUtils
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.util.Base64Utils
import org.springframework.util.DigestUtils

import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

class apiTdxToken implements ServiceBackInvoke {

    private static final Log log = LogFactory.getLog(apiTdxToken.class);
    /**
     * 编码
     */
    private static final String ENCODING = "UTF-8";
    /**
     * 算法定义
     */
    private static final String AES_ALGORITHM = "AES";
    /**
     * 指定填充方式
     */
    private static final String CIPHER_PADDING = "AES/ECB/PKCS5Padding";



    @Override
    String doCallBack(EliteBean eliteBean, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {

        JdbcTemplate jt = new JdbcTemplate(eliteBean.getDataSource());


        String sql = "select WEBSERVICEURL From sysc_interface where WEBTYPE='ZJ_TDX'";
        List<Map<String, Object>> createlist = jt.queryForList(sql)
        //调用Token接口
        if (createlist.size() > 0) {
            Map createmap = createlist.get(0)
            String url = createmap.get("WEBSERVICEURL");

            //      String tokenresult = Util.doHttpGet(url+"/rest/workgroup/token", "UTF-8", 5000, 0)
            //    JSONObject tokenjson = JSONObject.fromObject(tokenresult)

            //OkHttpClient httpClient = new OkHttpClient();
            String account = KHDBConfig.getParam(eliteBean, "TDX_ID", "");//token 账号
            String password = KHDBConfig.getParam(eliteBean, "TDX_MM", "");//token 密码
            String tokenurl = url + "/rest/workgroup/token";

            PropertiesUtil cfg = new PropertiesUtil();
            String proxyIp = cfg.readValue("QingNiu.ProxyIP");
            String proxyPort = cfg.readValue("QingNiu.ProxyPort");

             String  responseBody = HttpClientProxy.sendGet(tokenurl,"",proxyIp, proxyPort as int) ;

            //Response response = httpClient.newCall(request).execute();
            //String responseBody = response.body().string();
            log.debug("[浙江泰迪熊获取token]step1: got response -> " + responseBody.toString());

            JSONObject jobj = JSON.parseObject(responseBody) as JSONObject;
            log.debug("[浙江泰迪熊获取token]sstep1: got www_Authenticate -> " + jobj.getString("www_Authenticate"));

            HashMap<String, String> authMap = parse(jobj.getString("www_Authenticate"));
            String content = buildAuthHeader(tokenurl, authMap, account, password);
            log.debug("[浙江泰迪熊获取token]sstep2: generate Authorization: " + content);
            Map<String,String> headMap=new HashMap<String,String>();

            headMap.put("Authorization",content);
            String  responseBody2= doHttpGetReturnResponse(tokenurl,"UTF-8", 30000 as int, 0 as int,headMap,"",proxyIp, proxyPort as int, true as boolean) ;

            log.debug("[浙江泰迪熊获取token]sstep3: got response -> " + responseBody2.toString());

            JSONObject jobj2 =JSONObject.fromObject(responseBody2);


            JSONObject jobj3 = JSONObject.fromObject(KHUtil.GetJV(jobj2 as org.json.JSONObject,"body")) as JSONObject;
            log.debug("[浙江泰迪熊获取token]sstep4: got token -> " + KHUtil.GetJV(jobj3 as org.json.JSONObject,"token"));

           // String token = jobj2.getString("token");

            log.debug("[浙江泰迪熊调用接口获取Token]JSON返回：" + jobj3.toString());


            return jobj3.toString();
        }
    }


    public static String sendGet(String url, String param, String pIP, int pPort,String Authorization) {
        String result = "";
        BufferedReader in1 = null;

        try {
            log.info("发送请求URL:" + url);
            log.info("发送请求参数:" + param);
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            URLConnection connection = null;
            if (pIP != null && pIP.length() > 0) {
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(pIP, pPort));
                connection = realUrl.openConnection(proxy);
            } else {
                connection = realUrl.openConnection();
            }

            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Authorization", Authorization);
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            connection.setConnectTimeout(30000);
            connection.setReadTimeout(30000);
            connection.connect();
            Map<String, List<String>> map = connection.getHeaderFields();
            log.info("遍历所有的响应头字段...");
            Iterator var10 = map.keySet().iterator();

            while(var10.hasNext()) {
                String key = (String)var10.next();
                log.debug(key + "--->" + map.get(key));
            }

            String line;

            for(in1 = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); (line = in1.readLine()) != null; result = result + line) {
            }
        } catch (Exception var20) {
            log.error("发送GET请求出现异常！" + var20.getMessage());
            var20.printStackTrace();
        } finally {
            try {
                if (in1 != null) {
                    in1.close();
                }
            } catch (Exception var19) {
                var19.printStackTrace();
            }

        }

        log.info("发送返回信息:" + result);
        return result;
    }

/**
 *  加密
 *
 * @param content 待加密内容
 * @param aesKey 密码
 * @return
 */
    public static String encrypt(String content, String aesKey) {
        if (StringUtils.isBlank(content)) {
            log.info("AES encrypt: the content is null!");
            return null;
        }
        //判断秘钥是否为16位
        if (StringUtils.isNotBlank(aesKey) && aesKey.length() == 16) {
            try {
                //对密码进行编码
                byte[] bytes = aesKey.getBytes(ENCODING);
                //设置加密算法，生成秘钥
                SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                // "算法/模式/补码方式"
                Cipher cipher = Cipher.getInstance(CIPHER_PADDING);
                //选择加密
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
                //根据待加密内容生成字节数组
                byte[] encrypted = cipher.doFinal(content.getBytes(ENCODING));
                //返回base64字符串
                return Base64Utils.encodeToString(encrypted);
            } catch (Exception e) {
                log.info("AES encrypt exception:" + e.getMessage());
                throw new RuntimeException(e);
            }

        } else {
            log.info("AES encrypt: the aesKey is null or error!");
            return null;
        }
    }
/**
 * 解密
 *
 * @param content 待解密内容
 * @param aesKey 密码
 * @return
 */
    public static String decrypt(String content, String aesKey) {
        if (StringUtils.isBlank(content)) {
            log.info("AES decrypt: the content is null!");
            return null;
        }
        //判断秘钥是否为16位
        if (StringUtils.isNotBlank(aesKey) && aesKey.length() == 16) {
            try {
                //对密码进行编码
                byte[] bytes = aesKey.getBytes(ENCODING);
                //设置解密算法，生成秘钥
                SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                // "算法/模式/补码方式"
                Cipher cipher = Cipher.getInstance(CIPHER_PADDING);
                //选择解密
                cipher.init(Cipher.DECRYPT_MODE, skeySpec);

                //先进行Base64解码
                byte[] decodeBase64 = Base64Utils.decodeFromString(content);

                //根据待解密内容进行解密
                byte[] decrypted = cipher.doFinal(decodeBase64);
                //将字节数组转成字符串
                return new String(decrypted, ENCODING);
            } catch (Exception e) {
                log.info("AES decrypt exception:" + e.getMessage());
                throw new RuntimeException(e);
            }

        } else {
            log.info("AES decrypt: the aesKey is null or error!");
            return null;
        }
    }


  public    static String buildAuthHeader(String uri, Map<String, String> authMap, String user, String password) {
        String realm = authMap.get("realm");
        realm = realm.substring(1, realm.length() - 1);
        String nonce = authMap.get("nonce");
        nonce = nonce.substring(1, nonce.length() - 1);
        String qop = authMap.get("qop");
        qop = qop.substring(1, qop.length() - 1);

        String opaque = authMap.get("opaque");

         def ha1 = DigestUtils.md5DigestAsHex(user+ ":" + realm + ":" + password as byte[]);

        def ha2 = DigestUtils.md5DigestAsHex("GET:" + uri as byte[]);
        String cnonce = UUID.randomUUID().toString();
        def hashResponse = DigestUtils.md5DigestAsHex(ha1 + ":" + nonce + ":00000001:" + cnonce + ":" + qop + ":" + ha2 as byte[] );

        StringBuilder challengeText = new StringBuilder("Digest username=\"");
        challengeText.append(user).append("\",");
        challengeText.append("realm=\"").append(realm).append("\",");
        challengeText.append("nonce=\"").append(nonce).append("\",");
        challengeText.append("uri=\"").append(uri).append("\",");
        challengeText.append("qop=\"").append(qop).append("\",");
        challengeText.append("nc=\"").append("00000001").append("\",");
        challengeText.append("cnonce=\"").append(cnonce).append("\",");
        challengeText.append("response=\"").append(hashResponse).append("\",");
        challengeText.append("opaque=").append(opaque);

        return challengeText.toString();
    }

    public static boolean isEmpty(String msg) {
        if (msg != null && !msg.isEmpty()) {
            return false;
        }
        return true;
    }

    public static HashMap<String, String> parse(String authHeader) {
        HashMap<String, String> headerMap = null;
        String header = authHeader.substring(authHeader.lastIndexOf("Digest") + "Digest ".length());
        if (!isEmpty(header)) {
            headerMap = new HashMap<String, String>();
            String[] params = header.split(",");
            if (params != null && params.length > 0) {
                for (String param : params) {

                    String[] data = param.split("=");
                    String key = data[0].trim();
                    String value = "";

                    if (data.length > 1) {
                        value = data[1].trim();
                    }

                    headerMap.put(key, value);
                }
            }
        }
        return headerMap;
    }

    public static JSONObject doHttpGetReturnResponse(String url, String charset, int timeout, int enableSSLflag, Map headMap, String sslstr, String proxyIP, int proxyPort, boolean proxyFlag) throws Exception {
        JSONObject obj = new JSONObject();
        HttpGet httpgets = new HttpGet(url);
        if (headMap != null) {
            Iterator entries = headMap.entrySet().iterator();

            while(entries.hasNext()) {
                Map.Entry entry = (Map.Entry)entries.next();
                String key = (String)entry.getKey();
                log.debug("key:" + key);
                String value = (String)entry.getValue();
                log.debug("value:" + value);
                httpgets.addHeader(key, value);
            }
        }

        String content = "";
        DefaultHttpClient httpClient = new DefaultHttpClient();
        if (proxyFlag) {
            HttpHost proxy = new HttpHost(proxyIP, proxyPort);
            httpClient.getParams().setParameter("http.route.default-proxy", proxy);
        }

        httpClient.getParams().setParameter("http.connection.timeout", timeout);
        httpClient.getParams().setParameter("http.socket.timeout", timeout);
        if (enableSSLflag == 1) {
            enableSSL(httpClient, sslstr);
        }

        HttpResponse httpResponse = httpClient.execute(httpgets);
        Header[] responseHead = httpResponse.getAllHeaders();
        HttpEntity httpEntity = httpResponse.getEntity();
        if (httpEntity != null) {
            content = EntityUtils.toString(httpEntity, charset);
        }

        httpClient.clearRequestInterceptors();
        httpClient.clearResponseInterceptors();
        httpClient.close();
         obj.put("body", content);
      //  obj.put("head", responseHead);
        return obj;
    }


}
